package org.rency.ues.engine.manager.impl;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.rency.ues.domain.support.Certification;
import org.rency.ues.engine.manager.CertificationManager;
import org.rency.ues.engine.repository.CertificationRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * $TODO
 *
 * @author: Created by user_rcy@163.com on 2016/07/31.
 * @version: V1.0.0
 * @since JDK 1.8
 */
public class CertificationManagerImpl implements CertificationManager,InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(CertificationManagerImpl.class);

    private ConcurrentHashMap<String, Certification> certifications = new ConcurrentHashMap<String, Certification>();

    private AtomicLong latestSerialNo = new AtomicLong(0L);

    private CertificationRepository certificationRepository;

    private void init(){
        if(!this.loadCertification()){
            throw new RuntimeException("初始化加载证书失败.");
        }
    }

    private boolean loadCertification(){
        List<Certification> certList = new ArrayList<Certification>();
        Long maxSerialNo = latestSerialNo.get();
        try {
             certList.addAll(certificationRepository.loadAll());
        } catch (Exception e) {
            logger.error("初始化加载证书异常.",e);
            return false;
        }
        if(CollectionUtils.isEmpty(certList)){
            logger.info("初始化加载证书为空.");
            return false;
        }
        for(Certification cert : certList){
            if(this.certifications.containsKey(cert.getSerialNo())){
                continue;
            }
            this.certifications.put(cert.getSerialNo(),cert);
            Long serialNo = Long.parseLong(cert.getSerialNo());
            maxSerialNo = Long.max(maxSerialNo,serialNo);
        }
        latestSerialNo.set(maxSerialNo);
        logger.info("初始化加载证书结束,共[{}]条.",this.certifications.size());
        return true;
    }

    @Override
    public Certification getCertification(String serialNo) {
        logger.info("获取证书载体,序列号:{}.",serialNo);
        if(StringUtils.isBlank(serialNo)){
            serialNo = this.getLastedSerialNo();
        }
        Certification cert = this.certifications.get(serialNo);
        if(cert == null){
            this.refreshAll();
            cert = this.certifications.get(serialNo);
        }
        return cert;
    }

    @Override
    public X509Certificate getX509(String serialNo) {
        Certification cert = this.getCertification(serialNo);
        if(cert == null){
            return null;
        }
        return cert.getCertificate();
    }

    @Override
    public String getLastedSerialNo() {
        return latestSerialNo.get()+"";
    }

    @Override
    public String getPubCert() {
        String lastestSerial = this.getLastedSerialNo();
        Certification cert = this.certifications.get(lastestSerial);
        return cert.getCertBase();
    }

    @Override
    public void refreshAll() {
        this.loadCertification();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.init();
    }

    public void setCertificationRepository(CertificationRepository certificationRepository) {
        this.certificationRepository = certificationRepository;
    }

}
